/****************************************
** 说明：    员工管理系统服务器
****************************************/

#include "server_module.h"
#include "display_login.h"

/*   命令对应关系    */
// 管理员
    // A -- 添加普通用户
    // B -- 查询所有用户
    // C -- 修改用户密码
    // D -- 删除指定用户
    // E -- 显示当前服务器文件
    // F -- 向服务器上传文件
    // G -- 从服务器下载文件
    // H -- 管理员退出登陆，返回一级菜单 -- 删除指定用户

// 普通用户
	// 1 -- 查看本地用户信息
	// 2 -- 修改本地用户密码
	// 3 -- 查询其他人特定信息
	// 4 -- 显示当前服务器文件
	// 5 -- 从服务器下载文件
	// 6 -- 普通用户退出登陆返回一级菜单

/* 变量集合 */
struct variable_struct {
    int server_fd;                       // 服务器套接字描述符
    int client_fd;                       // 客户端套接字描述符
    struct sockaddr_in server_addr;      // 服务器套接字信息配置结构体
    char cmd;
	pid_t pid;                           // 进程号
    sqlite3 *db;                         // 数据库操作句柄
}variable;

//存储登陆信息结构体
struct login_inform logininfo;


/* 主程序 */
int main(int argc, const char *argv[]) {
    /* 创建套接字，并返回文件描述符 */
    variable.server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == variable.server_fd) {
        perror("fail to socket");
        exit(EXIT_FAILURE);
    }

    char *errmsg;
    // 打开数据库，如果没有则创建
	if (sqlite3_open("./staff.db", &variable.db) != SQLITE_OK) {
		printf("%s\n", sqlite3_errmsg(variable.db));
	} else {
		printf("sqlite is open done\n");
	}
    /* 配置地址和端口信息 */
    variable.server_addr.sin_family = AF_INET;
    variable.server_addr.sin_port = htons(atoi(argv[2]));
    variable.server_addr.sin_addr.s_addr = inet_addr(argv[1]);   
    bzero(variable.server_addr.sin_zero, 8);

    /* 套接字与地址信息绑定 */
    if (bind(variable.server_fd, (struct sockaddr *)&variable.server_addr, sizeof(struct sockaddr)) == -1) {
        perror("fail to bind");
        exit(EXIT_FAILURE);
    }

    /* 监听请求 */
    if (listen(variable.server_fd, 10) == -1) {  // 设置最大请求数为10
        perror("fail to listen");
        exit(EXIT_FAILURE);
    }

    /* 接受客户端的连接请求，若没有则阻塞 */
    socklen_t client_addr_len;
    struct sockaddr_in client_addr;
    client_addr_len = sizeof(struct sockaddr);

	signal(SIGCHLD, SIG_IGN);

    while (1) {
        // 接收客户端连接请求
        if ((variable.client_fd = accept(variable.server_fd, (struct sockaddr *)&client_addr, &client_addr_len)) == -1) {
            perror("fail to accept");
            exit(EXIT_FAILURE);
        }
        printf("connect from [%s : %d]\n", inet_ntoa(client_addr.sin_addr),\
            ntohs(client_addr.sin_port));
        if ((variable.pid = fork()) < 0) {
            perror("fail to fork");
            exit(EXIT_FAILURE);
        } else if (variable.pid == 0) {    // 客户端连接成功，创建子进程进行通讯
			int ret;
			while(1)
			{
				// 管理员与用户登陆
				if((ret = login_in(variable.client_fd, &logininfo, variable.db)) < 0)
				{
					break;			// 客户端选择退出				
				}else if (ret > 0){
					continue;		// 客户端登陆失败
				}

				while(1)
				{
					// 接受客户端命令
					if(recv(variable.client_fd, &variable.cmd, 1, 0) == 0)
					{
						break;
					}
					printf("cmd:%c\n", variable.cmd);
					if (variable.cmd == 'A')			// 增加用户
					{
						add_user(variable.client_fd, variable.db);
					}else if ((variable.cmd == 'B')||(variable.cmd == '1')){	// 查询用户
						query_user(variable.client_fd, variable.db);
					}else if ((variable.cmd == 'C')||(variable.cmd == '2')){	// 更新用户
						update_user(variable.client_fd, variable.db);
					}else if (variable.cmd == 'D'){		// 删除用户	
						del_user(variable.client_fd, variable.db);			
					}else if ((variable.cmd == 'H')||(variable.cmd == '6')){	// 客户端退回至一级菜单
						break;
					}else if (variable.cmd == '3'){		// 普通用户查询其他用户指定信息
						user_query_other_people(variable.client_fd, variable.db);
					}else if ((variable.cmd == 'E')||(variable.cmd == '4')){	// 显示服务器文件
						list_file(variable.client_fd);
					}else if (variable.cmd == 'F'){		// 向服务器上传文件
						put_file(variable.client_fd);
					}else if ((variable.cmd == 'G')||(variable.cmd == '5')){	// 从服务器下载文件
						load_file(variable.client_fd);
					}
				}				
			}
        } else {
        }
    }

	sqlite_close(variable.db);
    /* 关闭套接字 */
    close(variable.client_fd);
    close(variable.server_fd);
    
    return 0;
}



